iT邦幫忙

2023 iThome 鐵人賽

DAY 23
0

上一篇我用 wkhtmltopdf 、 laravel-snappy 將變數放入 html 生成 PDF 檔案,因為業主說 PDF 開啟時需要密碼保護,搜尋了一下 wkhtmltopdf / laravel-snappy 似乎沒有加入密碼保護功能,所以後來找到 pdftk 套件。

https://ithelp.ithome.com.tw/upload/images/20231008/201628932rRxvKudrA.png

pdftk 安裝

  1. 官方github:https://github.com/mikehaertl/php-pdftk

  2. 需要在開發環境安裝,然後再用composer install 安裝在專案中

    sudo apt install pdftk                   // 安裝在開發環境,例如本機
    composer require mikehaertl/php-pdftk    // composer 安裝在專案根目錄
    

這邊要注意是兩個都要安裝唷!我用的時候還一直笨笨的以為只要裝一個,然後網頁一直跳出 pdftk not found…

pdftk 使用

相較於 wkhtmltopdf,pdftk 更簡單一些,pdftk 使用說明也寫得滿清楚,概念上就是把存在專案裡面的 pdf 檔案 new PDF(’檔案路徑’) 出來,對 PDF 進行操作後,再存到專案或是下載。

use mikehaertl\pdftk\Pdf;

$pdf = new Pdf('/path/my.pdf');

$result = $pdf->allow('AllFeatures')      // Change permissions
    ->setPassword($pw)          // Set owner password 管理員密碼
    **->setUserPassword($pw)      // Set user password 開啟檔案的密碼**
    ->passwordEncryption(128)   // Set password encryption strength 密碼加密
    ->saveAs('new.pdf');        // 檔名

if ($result === false) {
    $error = $pdf->getError();
}
  • 我自己在實作中,如果沒有把 $pdf->getError() 放入程式碼會報錯

碰到的問題

pdftk not found

來,請幫我回到本篇第一個標題的內容!

人家使用說明就說了要安裝在電腦本機,然後再用composer安裝在專案,你是不是少了哪一個!!

檔案路徑問題

由於我自己對於 Laravel 的檔案路徑位置太不熟悉,導致不斷取不到正確的 PDF 檔案,一直報錯,差點想砸了電腦哈哈哈哈。(這告訴大家 filesystem 要好好學~~)

https://ithelp.ithome.com.tw/upload/images/20231008/201628932rRxvKudrA.png

如同最前面那張圖,我是用 laravel-snappy 搭配 pdftk 產生加密的 PDF 檔案,因此整個程式碼會變成:

  1. snappy 產生PDF ,存放在專案資料夾
    這裡的指定資料夾考量到資安問題,如果放在 /public/storage 有可能遭有心人士鑽漏洞,畢竟這兩個資料夾會連結對外公開,此時的 PDF 檔案又是未加密的,可能洩漏個資。所以最後直接放在專案根目錄 /groups,直接在專案根目錄建立新資料夾。

    $group = Group::find($groupId);
    
    // 內容 html
    $pdf = SnappyPdf::loadView('groupPdf', [
       'group' => $group,
    ]);
    
    // 頁首 html
    $header = view('groupHeaderPdf', [  
        'group' => $group,
    ]);
    
    // 用 setOption 加入頁首
    $pdf->setOption('header-html', $header)
        ->save(base_path("groups/$fileName.pdf"), true);
    
  2. pdftk 到 /groups 取得指定的 pdf 檔案,new 一個新的 pdf 檔案,並且加入權限和密碼設定,最後存放在相同資料夾 /groups

    // pdftk 加入檔案密碼保護
    $pdftk = new Pdf(**base_path("groups/$fileName.pdf")**);
    $result = $pdftk->allow('AllFeatures')->setUserPassword($userPassword)
        ->passwordEncryption(128)
        ->saveAs(**base_path("groups/$fileName.pdf")**);
    
    if ($result === false) {
        return SystemHelper::errorMsg(__($pdftk->getError()));
    }
    
    return Storage::disk('groups')->download("$fileName.pdf");
    

上一篇
匯出加密的 PDF(1):wkhtmltopdf、laravel-snappy
下一篇
後端必備技能: 認識 API 文件
系列文
Laravel 後端菜鳥可以知道的流程概念30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言